package cn.gov.cbrc.east.verify;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * 项目名称：EastUpload<br>
 * *********************************<br>
 * <P>类名称：Verify</P>
 * *********************************<br>
 * <P>类描述：公式校验
 * 		1、表达式
 * 		2、验证值--都以数值传入
 * 		3、返回值 true false
 * 		注：方法不能重载，即不能有重名的方法
 * TODO  返回级别
 * </P>
 * 创建人：王川<br>
 * 创建时间：Jan 18, 2016 3:16:04 PM<br>
 * 修改人：王川<br>
 * 修改时间：Jan 18, 2016 3:16:04 PM<br>
 * 修改备注：<br>
 * @version 1.0<br>    
 */
public class Verify {
	
	static int[] locked;
	/**浮点正则表达式**/
	static Pattern pf = Pattern.compile("^[+-]?\\d*\\.?\\d*?$");
	/**整数正则表达式**/
	static Pattern pi = Pattern.compile("^[+-]?\\d*$");
	/**In类型正则表达式集合**/
	static Map<Integer, Pattern> inRegMap = new HashMap<Integer, Pattern>();
	/**Inm类型正则表达式集合**/
	static Map<Integer, Pattern> inmRegMap = new HashMap<Integer, Pattern>();
	/**Dw类型正则表达式集合**/
	static Map<Integer, Pattern> dwRegMap = new HashMap<Integer, Pattern>();
	/**Dwd类型正则表达式集合**/
	static Map<String, Pattern> dwdRegMap = new HashMap<String, Pattern>();
	/**
	 * <p>方法描述:空值校验 </p>
	 * <p>方法备注: </p>
	 * @param str 检验值
	 * @return
	 * <p>创建人：王川</p>
	 * <p>创建时间：Jan 19, 2016 2:32:20 PM</p>
	 *
	 */
	public static boolean Nvl(String str) {
    	if(str.startsWith("\""))
    		str = str.substring(1, str.length()-1);
    	if(str==null || "".equals(str))
    		return false;
    	return true;
    }
	
	/**
     * <p>方法描述:C n </p>
     * <p>方法备注:n位字符的固定长度 </p>
     * @param str 检验值
     * @param n 表示n位字符的固定长度
     * @return
     * <p>创建人：王川</p>
     * <p>创建时间：Jan 19, 2016 1:51:46 PM</p>
     *
     */
    public static boolean Cn(String str,int n){
    	//内容被""包围
    	if(str.startsWith("\""))
    		str = str.substring(1, str.length()-1);
    	if(str==null|| "".equals(str))
    		return true;
    	return str.length()==n;
    }
    
    /**
     * <p>方法描述: C..n </p>
     * <p>方法备注:n位字符的可变长度 </p>
     * @param str 检验值
     * @param m 最大值
     * @return
     * <p>创建人：王川</p>
     * <p>创建时间：Jan 19, 2016 1:54:11 PM</p>
     *
     */
    public static boolean Cnm(String str,int m){
    	//内容被""包围
    	if(str.startsWith("\""))
    		str = str.substring(1, str.length()-1);
    	if(str==null || "".equals(str))
    		return true;
    	return str.length()<=m;
    }
    
    /**
     * <p>方法描述:浮点数校验 </p>
     * <p>方法备注: </p>
     * @param str
     * @return
     * <p>创建人：王川</p>
     * <p>创建时间：Jan 19, 2016 2:21:41 PM</p>
     *
     */
    public static boolean F(String str){
    	if(str==null || "".equals(str))
    		return true;
    	//如果数字类型以" 开头则返回false
    	if(str.startsWith("\""))
    		return false;
        return pf.matcher(new BigDecimal(str).toPlainString()).matches();
    } 

    /**
     * <p>方法描述:整数校验 </p>
     * <p>方法备注: </p>
     * @param str
     * @return
     * <p>创建人：王川</p>
     * <p>创建时间：Jan 19, 2016 2:21:41 PM</p>
     *
     */
    public static boolean I(String str){
    	if(str==null || "".equals(str))
    		return true;
    	//如果数字类型以" 开头则返回false
    	if(str.startsWith("\""))
    		return false;
        return pi.matcher(str).matches();
    } 
    
    /**
     * <p>方法描述:I n </p>
     * <p>方法备注:n位整数的固定长度 </p>
     * @param str 检验值
     * @param n 表示n位整数的固定长度
     * @return
     * <p>创建人：王川</p>
     * <p>创建时间：Jan 19, 2016 1:51:46 PM</p>
     *
     */
    public static boolean In(String str,int n){
    	if(str==null || "".equals(str))
    		return true;
    	//如果数字类型以" 开头则返回false
    	if(str.startsWith("\""))
    		return false;
        return getInReg(n).matcher(str).matches();
    }
    
    /**
     * <p>方法描述: I..n </p>
     * <p>方法备注:n位整数的可变长度 </p>
     * @param str 检验值
     * @param m 最大值
     * @return
     * <p>创建人：王川</p>
     * <p>创建时间：Jan 19, 2016 1:54:11 PM</p>
     *
     */
    public static boolean Inm(String str,int m){
    	if(str==null || "".equals(str))
    		return true;
    	//如果数字类型以" 开头则返回false
    	if(str.startsWith("\""))
    		return false;
        return getInmReg(m).matcher(str).matches();
    }
    
    
    /**
     * <p>方法描述:Dw </p>
     * <p>方法备注: </p>
     * @param str
     * @param w 表示包含小数点前后字符位在内的整个字段最多字符位数
     * @return
     * <p>创建人：王川</p>
     * <p>创建时间：Mar 25, 2016 3:47:07 PM</p>
     *
     */
    public static boolean Dw(String str,int w){
    	if(str==null || "".equals(str))
    		return true;
    	//如果数字类型以" 开头则返回false
    	if(str.startsWith("\""))
    		return false;
        return getDwReg(w).matcher(str.replace(".", "")).matches();
    }
    
    /**
     * <p>方法描述: Dw.d </p>
     * <p>方法备注: 表示十进制小数可计算形式</p>
     * @param str 检验值
     * @param w 表示包含小数点前后字符位在内的整个字段最多字符位数
     * @param d 表示小数点后的最多字符位数
     * @return Dwd(ROW,20,2)
     * <p>创建人：王川</p>
     * <p>创建时间：Jan 19, 2016 1:49:38 PM</p>
     *
     */
    public static boolean Dwd(String str,int w,int d){
    	if(str==null || "".equals(str))
    		return true;
    	//如果数字类型以" 开头则返回false
    	if(str.startsWith("\""))
    		return false;
        return getDwdReg(w-d, d).matcher(str).matches();
    }
	
    /**
     * <p>方法描述:范围检验--标准取值校验 </p>
     * <p>方法备注: 单选校验</p>
     * @param str 检验值
     * @param sd 取值范围
     * @return
     * <p>创建人：王川</p>
     * <p>创建时间：Jan 19, 2016 2:00:29 PM</p>
     *
     */
    public static boolean Sd(String str,String sd){
    	//内容被""包围
    	if(str.startsWith("\""))
    		str = str.substring(1, str.length()-1);
    	if(str==null || "".equals(str))
    		return true;
    	if(str.indexOf(",") != -1)
    		return false;
    	return (sd+",").indexOf(str+",")!=-1;
    }
    
    /**
     * <p>方法描述:范围检验--标准取值校验 </p>
     * <p>方法备注: 多选校验</p>
     * @param str
     * @param sd
     * @return
     * <p>创建人：王川</p>
     * <p>创建时间：Jan 21, 2016 9:07:42 AM</p>
     *
     */
    public static boolean Sdm(String str,String sd){
    	//内容被""包围
    	if(str.startsWith("\""))
    		str = str.substring(1, str.length()-1);
    	if(str==null || "".equals(str))
    		return true;
    	String[] sa = str.split(",");
    	for(String s:sa){
    		if((sd+",").indexOf(s+",") ==-1)
    			return false;
    	}
    	return true;
    }
    
    /**
     * 根据要求长度从map中获取整数正则表达式
     * @param length 整数长度
     * @return
     */
    public static Pattern getInReg(int length){
    	Pattern p = inRegMap.get(length);
    	if(p == null){
    		String regex = "^[+-]?\\d{"+length+"}$";
        	p = Pattern.compile(regex);
        	inRegMap.put(length, p);
    	}
    	return p;
    }
    /**
     * 根据最大长度从map中获取整数正则表达式
     * @param max 最大长度
     * @return
     */
    public static Pattern getInmReg(int max){
    	Pattern p = inmRegMap.get(max);
    	if(p == null){
    		String regex = "^[+-]?\\d{0,"+max+"}$";
        	p = Pattern.compile(regex);
        	inmRegMap.put(max, p);
    	}
    	return p;
    }
    /**
     * 获取Dw类型正则表达式
     * @param w 表示包含小数点前后字符位在内的整个字段最多字符位数
     * @return
     */
    public static Pattern getDwReg(int w){
    	Pattern p = dwRegMap.get(w);
    	if(p == null){
    		String regex = "^[+-]?\\d{0,"+w+"}$";
        	p = Pattern.compile(regex);
        	dwRegMap.put(w, p);
    	}
    	return p;
    }
    /**
     * 获取Dw类型正则表达式
     * @param w 表示包含小数点前后字符位在内的整个字段最多字符位数
     * @param d 表示小数点后的最多字符位数
     * @return
     */
    public static Pattern getDwdReg(int w,int d){
    	Pattern p = dwdRegMap.get(w+"|"+d);
    	if(p == null){
    		String regex = "^[+-]?[0]*?\\d[0-9]{0,"+w+"}(\\.\\d+)?$";
        	p = Pattern.compile(regex);
        	dwdRegMap.put(w+"|"+d, p);
    	}
    	return p;
    }
}
